package com.mju.service.elastic;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mju.model.Teacher;
import com.mju.model.dto.DurationDTO;
import com.mju.service.TeacherService;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.ElasticsearchException;
import co.elastic.clients.elasticsearch.core.BulkRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class ElasticService {
	@Autowired
	private ElasticsearchClient esClient;
	@Autowired
	private TeacherService teacherService;

	// 创建索引
	public void createIndex() throws ElasticsearchException, IOException {
		
		String indexName=getIndexName();//获取索引名称

		BooleanResponse hasIndex = esClient.indices().exists(e -> e.index(indexName));
		if (!hasIndex.value()) { // 如果索引不存在，则创建索引
			esClient.indices()
					.create(c -> c.index(indexName)
							.settings(s -> s.analysis(a -> a
									.filter("my_synonym_filter",
											f -> f.definition(
													d -> d.synonym(v -> v.synonyms("前后端,前端后端", "机器学习,人工智能,AI"))))
									.analyzer("my_synonyms",
											aly -> aly.custom(
													my -> my.filter("my_synonym_filter").tokenizer("ik_smart")))))
							.mappings(m -> m.properties("teacherno", p -> p.text(t -> t))
									.properties("teachername", p -> p.text(t -> t)).properties("memo",
											p -> p.text(t -> t.analyzer("my_synonyms").searchAnalyzer("ik_smart")))));
		};
	}

	// 批量把数据库中导师信息插入到Elastic文档，教师号作为id
	public void batchToDoc() throws ElasticsearchException, IOException {
		
		String indexName=getIndexName();//获取索引名称

		// 获取MySQL所有待插入数据
		List<Teacher> teachers = teacherService.getList();

		BulkRequest.Builder br = new BulkRequest.Builder();
//		teachers.stream().forEach(x -> br.operations(opt -> opt
//							.index(idx -> idx
//									.index(indexName)
//									.id(x.getTeacherno())
//									.document(x))
//				)
//		);
		
		teachers.stream().forEach(
				x -> br.operations(opt-> opt
				  .create(c->c.index(indexName)
						      .id(x.getTeacherno())
						      .document(x)
						  )
				  ));
		
		esClient.bulk(br.build());
	}
	
	//全文搜索memo字段
	public List<Map<String,String>> esByMemo(String keyword) 
			throws ElasticsearchException, IOException{
		
		String indexName=getIndexName();//获取索引名称
		
		SearchResponse<Teacher> response = esClient.search(s->s
				.index(indexName)
				.query(q->q.match(m->m.field("memo")
						              .query(keyword)
						          ))
				.highlight(h->h.fields("memo",f->f 
							   .preTags("<span style=\"color:blue\">")
							   .postTags("</span>")))
				, Teacher.class);
		List<Map<String,String>> result=new ArrayList<>();
		
		for (Hit<Teacher> t : response.hits().hits()) {		
			Map<String,String> m=new HashMap<>();		
			m.put("teacherno", t.source().getTeacherno());
			m.put("teachername",t.source().getTeachername());
			m.put("memo", t.highlight().get("memo").get(0));
			result.add(m);
		}		
		return result;
	}
	
	private String getIndexName() {
		// 索引按照学期
		DurationDTO dto = teacherService.selectDuaration();
		int term = dto.getTerm();// 获取学期
		String indexName = "paper_" + term;// 索引名字
		return indexName;
	}
}
